from PySide6.QtWidgets import (QApplication, QSplitter, QTextEdit, QWidget,
                               QVBoxLayout, QStackedWidget, QFileDialog,
                               QLabel)
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QObject, QThread, QTimer, Qt, Signal
from PySide6.QtGui import QIcon, QGuiApplication, QPixmap
import sys
import time
import pyperclip
from OCR_Capture import CaptureWidget
import GridSpilt
import pytesseract


class MainWidget(QWidget):
    # Signals
    doTable2String = Signal()

    def __init__(self):
        super().__init__()

        # combobox里对应的语言名称
        self._lang_dic = {
            'English': 'eng',
            'Chinese-sim': 'chi_sim',
            'Japanese': 'jpn',
            'Korean': 'kor'
        }

        self.initUi()  # 初始化界面
        self.setDefaultSettings()  # 设置默认参数

        # 表格识别线程的配置
        self.gridThread = QThread()
        self.gridworker = GridSpilt.GridWorker()
        # 表格识别多线程信号关联
        self.gridworker.moveToThread(self.gridThread)
        self.gridThread.finished.connect(QObject.deleteLater)
        self.gridworker.resultReady.connect(self.printTable)
        self.doTable2String.connect(self.gridworker.table2str)

    def initUi(self):
        #################### capturetool窗口的设置 ####################
        # 从文件加载ui
        self._captureToolWidget = QUiLoader().load(
            './ui/OCRCaptureWidget.ui')  # 主页面
        # self._captureToolWidget.setWindowFlag(Qt.FramelessWindowHint)
        self._gridWidget = QUiLoader().load('./ui/grid.ui')  # 表格识别页面
        self._gridCollapse = 1  # 标记是否折叠表格识别页面，1折叠，-1不折叠

        # splitter用来给主界面做折叠功能
        self._splitter = QSplitter(self)
        self._splitter.addWidget(self._captureToolWidget)  # index[0]
        self._splitter.addWidget(self._gridWidget)  # index[1]
        self._splitter.setCollapsible(0, False)  # 主界面不能折叠

        # 设置占位符
        self._captureToolWidget.textBrowser.setPlaceholderText(
            '  Waiting for process...')

        # 设置默认背景图
        fileName = "./icons/default_label.jfif"
        pixmap = QPixmap(fileName)
        # pixmap.scaled(pixmap.size(), .KeepAspectRatio)
        self._gridWidget.table_img.setPixmap(pixmap)
        self._gridWidget.table_img.setScaledContents(True)  # 图片自适应窗口大小

        #################### setting界面的设置 ####################
        self._settingWidget = QUiLoader().load('./ui/setting.ui')
        self._settingWidget.theme_comboBox.addItem('light')
        self._settingWidget.theme_comboBox.addItem('dark')
        self._settingWidget.lang_comboBox.addItem('English')
        self._settingWidget.lang_comboBox.addItem('Chinese-sim')
        self._settingWidget.lang_comboBox.addItem('Japanese')
        self._settingWidget.lang_comboBox.addItem('Korean')

        # 堆叠窗口
        self._stackWidget = QStackedWidget()
        self._stackWidget.addWidget(self._splitter)  # 添加第一个窗口（主窗口）
        self._stackWidget.addWidget(self._settingWidget)  # 添加第二个窗口（截图窗口）

        # 主界面只放一个layout，作为QStackedWidget的容器
        self._layout = QVBoxLayout()
        self._layout.addWidget(self._stackWidget)
        self.setLayout(self._layout)
        self.setWindowFlag(Qt.WindowStaysOnTopHint)  # 页面置于最上层
        self.setWindowTitle('OCR Capture Tool')

        # 窗口居中
        self.setGeometry(0, 0, 300, 600)
        screen = QGuiApplication.primaryScreen()  # 获取桌面窗口的尺寸
        size = self.geometry()
        self.move(
            (screen.size().width() - size.width()) / 2,
            (screen.size().height() - size.height()) / 2)  # 调用move移动到指定位置

        # 设置主界面尺寸
        self._windowWidth = 350
        self._windowHeight = 700
        self.setMinimumWidth(self._windowWidth)
        self.setMinimumHeight(self._windowHeight)
        self._splitter.setSizes([self._windowWidth, 0])  # 设置折叠界面宽度，默认为0（折叠）

        # 关联按钮点击信号和槽
        self._captureToolWidget.add_content_button.clicked.connect(
            self.handleNewRequest)
        self._captureToolWidget.copy_button.clicked.connect(
            self.copystr2clipboard)
        self._captureToolWidget.clear_button.clicked.connect(self.clearText)
        self._captureToolWidget.grid_button.clicked.connect(self.gridCollapse)
        self._captureToolWidget.setting_button.clicked.connect(
            self.switch2settingPage)  # 跳转到setting页面
        self._gridWidget.openfile_button.clicked.connect(
            self.openTableFromFile)
        self._gridWidget.table2grid_button.clicked.connect(self.table2str)
        self._settingWidget.prevPage_button.clicked.connect(
            self.switch2mainPage)  # 跳转到main页面
        self._settingWidget.theme_comboBox.currentTextChanged.connect(
            self.setThemeStyle)
        self._settingWidget.lang_comboBox.currentTextChanged.connect(
            self.setOCRLanguage)
        self._settingWidget.windowOnTop_checkbox.stateChanged.connect(
            self.changeWindowFlag)

    # 一些默认参数的设置
    def setDefaultSettings(self):
        self.setThemeStyle('light')  # 界面默认使用 light 风格
        self._lang = 'chi_sim'  # 识别语言默认为中文
        self._settingWidget.windowOnTop_checkbox.setChecked(True)  # 默认窗口置顶
        self._settingWidget.lang_comboBox.setCurrentIndex(1)

    # 处理新请求
    def handleNewRequest(self):
        if self.isVisible():
            self.setVisible(False)
        time.sleep(0.3)  # 不加延时太快的话可能来不及隐藏界面
        self._captureW = CaptureWidget(
            self._lang)  # 捕获窗口截图时创建CaptureWidget并覆盖整个屏幕
        self._captureW.show()

        # 收到信号后打印结果，关闭截图界面
        self._captureW.send_str_signal.connect(self.printResult)
        self._captureW.close_capture_signal.connect(self.close_capture_widget)

    # 打印结果
    def printResult(self, strFromImg):
        self._captureToolWidget.textBrowser.append(strFromImg)
        self.setVisible(True)

    # 打印表格内容
    def printTable(self, strFromImg):
        self._captureToolWidget.textBrowser.append(strFromImg)

    # 复制文本到系统剪贴板
    def copystr2clipboard(self):
        pyperclip.copy(self._captureToolWidget.textBrowser.toPlainText())

    # 清除文本框内容
    def clearText(self):
        self._captureToolWidget.textBrowser.clear()

    # 关闭截图界面
    def close_capture_widget(self):
        self._captureW.close()
        self.setVisible(True)

    # 折叠主界面
    def gridCollapse(self):
        self._gridCollapse = (-1) * self._gridCollapse
        if self._gridCollapse == 1:  # 折叠
            self.resize(self._windowWidth, self._windowHeight)      # 调整窗口大小
            self._splitter.setSizes([self._windowWidth, 0])         # 分配两个窗口的尺寸

        else:  # 展开
            self.resize(3 * self._windowWidth, self._windowHeight)
            self._splitter.setSizes([self._windowWidth, 2 * self._windowWidth])

    # 打开表格图片并显示
    def openTableFromFile(self):
        fileName = QFileDialog.getOpenFileName(
            self._gridWidget,
            "open image",
            filter="Image Files (*.png *.jpg *.bmp *.tif)")
        self.tableName = fileName[0]
        pixmap = QPixmap(fileName[0])  # 这里得到的 filename 是一个列表，第一个是文件名
        # pixmap.scaled(pixmap.size(), Qt.KeepAspectRatio)
        self._gridWidget.table_img.setPixmap(pixmap)
        self._gridWidget.table_img.setScaledContents(True)  # 图片自适应窗口大小

        self.gridworker.openImage(self.tableName)  # 初始化 gridworker 的图片路径

    # 表格识别
    def table2str(self):
        # 单线程写法（会造成UI假死）
        # imgs, rects, Intersections = GridSpilt.table_to_grid(
        #     self.tableName, 3000, 50, 500, 50)
        # for img in imgs:
        #     info = pytesseract.image_to_string(img, lang='chi_sim', timeout=5)
        #     self._captureToolWidget.textBrowser.append(info)

        # 多线程写法
        # 启动表格识别线程
        self.gridThread.start()
        # 发射信号启动表格识别
        self.doTable2String.emit()

    # 页面跳转
    def switch2settingPage(self):
        self._stackWidget.setCurrentIndex(1)

    def switch2mainPage(self):
        self._stackWidget.setCurrentIndex(0)

    # 设置主题样式
    def setThemeStyle(self, type):
        if type == 'dark':
            # load qss
            with open('./stylesheet/darkstyle.qss', 'r') as f:
                style = f.read()
                self.setStyleSheet(style)

            # icons
            self._captureToolWidget.add_content_button.setIcon(
                QIcon('./icons/scan-wh.png'))
            self._captureToolWidget.copy_button.setIcon(
                QIcon('./icons/copy-wh.png'))
            self._captureToolWidget.clear_button.setIcon(
                QIcon('./icons/clear-wh.png'))
            self._captureToolWidget.grid_button.setIcon(
                QIcon('./icons/grid-wh.png'))
            self._captureToolWidget.setting_button.setIcon(
                QIcon('./icons/setting-wh.png'))
            self._gridWidget.openfile_button.setIcon(
                QIcon('./icons/open-wh.png'))
            self._gridWidget.table2grid_button.setIcon(
                QIcon('./icons/process-wh.png'))
            self._settingWidget.prevPage_button.setIcon(
                QIcon('./icons/backup-wh.png'))
        elif type == 'light':
            # load qss
            with open('./stylesheet/lightstyle.qss', 'r') as f:
                style = f.read()
                self.setStyleSheet(style)

            # icons
            self._captureToolWidget.add_content_button.setIcon(
                QIcon('./icons/scan-b.png'))
            self._captureToolWidget.copy_button.setIcon(
                QIcon('./icons/copy-b.png'))
            self._captureToolWidget.clear_button.setIcon(
                QIcon('./icons/clear-b.png'))
            self._captureToolWidget.grid_button.setIcon(
                QIcon('./icons/grid-b.png'))
            self._captureToolWidget.setting_button.setIcon(
                QIcon('./icons/setting-b.png'))
            self._gridWidget.openfile_button.setIcon(
                QIcon('./icons/open-b.png'))
            self._gridWidget.table2grid_button.setIcon(
                QIcon('./icons/process-b.png'))
            self._settingWidget.prevPage_button.setIcon(
                QIcon('./icons/backup-b.png'))
        else:
            pass

    # 设置语言
    def setOCRLanguage(self, lang):
        self._lang = self._lang_dic[lang]

    # 设置窗口层次
    def changeWindowFlag(self, state):
        if state == Qt.Unchecked:
            self.setWindowFlag(Qt.WindowStaysOnTopHint, False)
            if not self.isVisible():  # 有时设置以后会自动隐藏窗口
                self.setVisible(True)
        elif state == Qt.Checked:
            self.setWindowFlag(Qt.WindowStaysOnTopHint, True)
            if not self.isVisible():  # 有时设置以后会自动隐藏窗口
                self.setVisible(True)
        else:
            pass


def main():
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon('./icons/OCRCapture.png'))  # 加载icon
    w = MainWidget()
    w.show()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()
